home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Add-On
/
Workbench Add-On - Volume 1.iso
/
Gfx
/
Edit
/
TSMorph
/
src
/
Frames.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-30
|
10KB
|
339 lines
// TSMorph - Amiga Morphing program
// Copyright (C) © 1993 Topicsave Limited
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// mpaddock@cix.compulink.co.uk
// include headers if not precompiled
#ifndef TSMORPH_H
#include "TSMorph.h"
#endif
LONG OldFrame; // Previous frame number
/* Go to the first frame
* the return value is that used by the main message loop
*/
int
FirstFrame(void) {
OldFrame=FrameNumber; // Store old frame
FrameNumber = GetNumber(TSMorphGadgets[GDX_Start]); // get starting frame
if (FrameNumber != OldFrame) { // if different
return ReopenPictures(); // try and move to new frame
}
return 1;
}
/* Go to the previous frame
* See FirstFrame()
*/
int
PrevFrame(void) {
OldFrame=FrameNumber;
if (FrameNumber > GetNumber(TSMorphGadgets[GDX_Start])) {
--FrameNumber; // previous frame
return ReopenPictures();
}
return 1;
}
/* Go to the previous frame
* See FirstFrame()
*/
int
GotoFrame(void) {
OldFrame=FrameNumber;
GetFrameNumber(); // Request frame number
if (FrameNumber != OldFrame) {
return ReopenPictures();
}
return 1;
}
/* Go to the next frame
* See FirstFrame()
*/
int
NextFrame(void) {
OldFrame=FrameNumber; // next determine last frame number
if (FrameNumber < (GetNumber(TSMorphGadgets[GDX_Start]) + GetNumber(TSMorphGadgets[GDX_Frames]) -1)) {
++FrameNumber;
return ReopenPictures();
}
return 1;
}
/* Go to the last frame
* See NextFrame()
*/
int
LastFrame(void) {
OldFrame=FrameNumber;
FrameNumber = GetNumber(TSMorphGadgets[GDX_Start]) + GetNumber(TSMorphGadgets[GDX_Frames]) - 1;
if (FrameNumber != OldFrame) {
return ReopenPictures();
}
return 1;
}
/* Request frame number
* returns TRUE if not cancelled
* selected frame is stored in FrameNumber
* This could use a nice sliding gadet requester - actually uses reqtools
*/
BOOL
GetFrameNumber(void) {
LONG Frames, Start; // Number of frames and starting frame
ULONG ret = 2; // loop flag
struct AmigaGuideMsg *agm; // for help
ULONG signals; // signals to wait on
struct rtHandlerInfo *rth; // reqtools stuff
Frames = GetNumber(TSMorphGadgets[GDX_Frames]); // Get frames and start frame
Start = GetNumber(TSMorphGadgets[GDX_Start]);
if (Frames > 1) { // No point displaying requester if 0 or 1 frame
// Determine Current frame number in correct range, using previously held value
FrameNumber = max(Start,FrameNumber);
FrameNumber = min(Start+Frames-1,FrameNumber);
DisableWindows(DI_GetFrame); // Disable all other windows
while (ret == 2) { // loop until Ok or Cancel (keep looping on Help)
// if no amigaguide then 2 will never be returned
ret = CALL_HANDLER; // reqtools stuff
if (rtGetLong((ULONG *)&FrameNumber,MyGetMsg(MSG_FRAMENO),NULL,
RT_ReqHandler, &rth,
RT_Window, TSMorphWnd, // same screen
RTGL_Min, Start,
RTGL_Max, Start+Frames-1,
RTGL_ShowDefault, TRUE,
RT_Underscore, '_',
RTGL_GadFmt, handle?MyGetMsg(MSG_OKHC):MyGetMsg(MSG_OKC), // if amigaguide then help gadget
TAG_END) == CALL_HANDLER) { // Opened requester
while (ret == CALL_HANDLER) { // Loop well no gadget selected
if (!rth->DoNotWait) { // Wait if poss.
signals = Wait(rth->WaitMask | ASig);
}
ret = rtReqHandlerA(rth,signals,NULL); // get gadget etc.
if (ret == 2) { // help gadget
help(H_FrameNumber);
}
if (signals & ASig) { // amigaguide message
while (agm = GetAmigaGuideMsg(handle)) {
ReplyAmigaGuideMsg(agm);
}
}
}
}
else { // otherwise error so default Cancel
ret = FALSE;
}
}
EnableWindows(); // enable all the windows
}
else {
if (!Frames) { // number of frames = 0 so error
Error(MyGetMsg(MSG_MUST1F),MyGetMsg(MSG_OK),NULL,HE_OneFrame);
ret = FALSE;
}
else { // number of frames = 1 so only one choice
FrameNumber = Start;
ret = TRUE;
}
}
return (BOOL)ret; // Cancel gadget is 0
}
/* Closes and reopens images using new frame (in FrameNumber)
* the return value is that used by the main message loop
*/
int
ReopenPictures(void) {
char buffer[257]; // Work buffer for points file name
LONG KeepFrame; // Temporary frame number
if (!Saved) { // if not saved then reset frame number and suggest user saves
KeepFrame = FrameNumber;
FrameNumber = OldFrame;
if (!SaveRequester()) {
return 1; // user cancelled
}
FrameNumber = KeepFrame; // either saved or abandoned so go to new frame
}
// Disable the windows and delete all the points
DisableWindows(DI_NextFrame);
DeleteAllPoints();
// Try and reopen image one and two
if (ReopenAPicture(GetString(TSMorphGadgets[GDX_FileOne]),&Pic1)) {
if (ReopenAPicture(GetString(TSMorphGadgets[GDX_FileTwo]),&Pic2)) {
// if ok then set up points filename and try and open
strcpy(TempFilename,savedfilename);
strcat(TempFilename,".%03ld");
sprintf(buffer,TempFilename,FrameNumber);
MyOpen(buffer,TRUE,FALSE); // Note! do not complain if no points file for thisframe (yet)
// enable the windows
EnableWindows();
// This is nasty!! (and probably unnecessary)
// but CWTitle is already held as the screen title,
// so do not want to be writing whilst intuition is reading
// Probably better to just call SetWindowTitles twice (first time to nothing)
// But that could cause the screen to flicker?
Forbid();
sprintf(CWTitle,MyGetMsg(MSG_TSMFRAME),FrameNumber);
Permit();
SetWindowTitles(ControlWindow,(UBYTE *)-1,CWTitle);
return 1; // It worked
}
}
EnableWindows();
return 3; // It did not work, so windows are closed, but keep going
}
/* Opens an image in an (already) open window
* This is all very convoluted stuff!
* returns : TRUE or FALSE for sucess failure
* filename : Name of file
* pic : pointer to a structure to hold all the stuff
*/
BOOL
ReopenAPicture(char *filename,struct Picture *pic) {
char dirname[257]; // filename storage
char *e = NULL; // first part of error message
char *e1 = NULL; // 2nd part of error message
LONG hnum = 0; // Help number for error
struct BitMap *OldBitMap = NULL; // BitMap to keep
// Set up new filename and display as screen title
// window title is done later (does not sound good?)
sprintf(dirname,filename,FrameNumber);
Forbid(); // Forbid whilst change window title - Nasty!!
strcpy(pic->filename,dirname);
Permit();
if (EGS) {
// Unload current frame (keeping bitmap)
unloadbrush(pic->ilbm);
// Try and load new brush - if this fails then flag error
if (!MyLoadBrush(pic,dirname)) {
e = (char *)-1;
}
if (!e) {
// fail if frame is not the same size as previous
if ((pic->width != Width) ||
(pic->height != Height)) {
e = MyGetMsg(MSG_FRAMESIZE);
hnum = HE_FAllSize;
}
else {
EI_SetWindowTitles(pic->EGS_Win,FilePart(pic->filename),pic->filename);
EG_CopyBitMapRastPort(pic->EGS_BitMap,pic->EGS_Win->RPort,0,0,pic->width,pic->height,0,0);
E_DisposeBitMap(pic->EGS_BitMap);
pic->EGS_BitMap = NULL;
}
}
else {
// failed loading new image
// so close file
closeifile(&(pic->ilbm->ParseInfo));
// set up error stuff
e = MyGetMsg(MSG_FAILLOAD);
e1 = dirname;
hnum = HE_LoadImage;
}
}
else {
SetWindowTitles(pic->Win,(UBYTE *)-1,pic->filename);
// if we do not allow zoom then the super bitmap is the actual bit map
// so initialise so we do not lose it when we unload the brush
if (!ZoomAllowed) {
// Zero out current bitmap picture
OldBitMap = pic->ilbm->brbitmap;
pic->ilbm->brbitmap = NULL;
}
// Unload current frame (keeping bitmap)
unloadbrush(pic->ilbm);
// Try and load new brush - if this fails then flag error
if (!MyLoadBrush(pic,dirname)) {
e = (char *)-1;
}
if (!e) {
// fail if frame is not the same size as previous
if ((pic->ilbm->Bmhd.w != Width) ||
(pic->ilbm->Bmhd.h != Height)) {
// if no zoom allowed then reset the bitmap to the original - freeing the new one
if (!ZoomAllowed) {
freebitmap(pic->ilbm);
pic->ilbm->brbitmap = OldBitMap;
}
e = MyGetMsg(MSG_FRAMESIZE);
hnum = HE_FAllSize;
}
else {
SetWindowTitles(pic->Win,FilePart(pic->filename),pic->filename); // This refreshes the titles
if (ZoomAllowed) {
// If we allow zoom then reset up BitScale stuff and scale or copy
pic->BitScaleArgs.bsa_SrcBitMap = pic->ilbm->brbitmap;
/* Either scale image 2x or straight copy */
if (Zoom) {
BitMapScale(&(pic->BitScaleArgs));
}
else {
BltBitMap(pic->ilbm->brbitmap,0,0,
&(pic->BitMap),0,0,
pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h,
0xC0,0xff,NULL);
}
}
else {
// Zoom is not allowed - so copy the new bit map to the old bit map
BltBitMap(pic->ilbm->brbitmap,0,0,
OldBitMap,0,0,
pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h,
0xC0,0xff,NULL);
// free the new bit map and set the image back
freebitmap(pic->ilbm);
pic->ilbm->brbitmap = OldBitMap;
// All because we can not change the bitmap of a super bitmap window
}
// Resync the display to the new bitmap display
LockLayerRom(pic->Win->RPort->Layer);
CopySBitMap(pic->Win->RPort->Layer);
UnlockLayerRom(pic->Win->RPort->Layer);
}
}
else {
// failed loading new image
// so close file
closeifile(&(pic->ilbm->ParseInfo));
if (!ZoomAllowed) {
// if no zoom allowed then free new bit map and restore old
freebitmap(pic->ilbm);
pic->ilbm->brbitmap = OldBitMap;
}
// set up error stuff
e = MyGetMsg(MSG_FAILLOAD);
e1 = dirname;
hnum = HE_LoadImage;
}
}
// display error (if required) and return status
if (e) {
if (e != (char *)-1) { // do not think this is possible?
Error(e,MyGetMsg(MSG_OK),e1,hnum); // we can actually display two error message
} // as MyLoadBrush() may have already displayed one
return FALSE;
}
else {
return TRUE;
}
}